package log

import (
	"fmt"
	"os"
	"sync"
)

var (
	hMutex   = sync.Mutex{}
	handlers = []func(){}
)

func runHandler(handler func()) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to write to run exit handler. error: %v\n", err)
		}
	}()

	handler()
}

func runHandlers() {
	hMutex.Lock()
	defer hMutex.Unlock()

	for _, handler := range handlers {
		runHandler(handler)
	}

	handlers = make([]func(), 0)
}

// 主动调用执行退出程序需要执行的函数
func Exit(code int) {
	runHandlers()
	os.Exit(code)
}

// 从尾部添加一个退出程序时需要执行的函数
func ExitHandlerAppend(handler func()) {
	hMutex.Lock()
	defer hMutex.Unlock()

	handlers = append(handlers, handler)
}

// 从头部添加一个退出程序时需要执行的函数
func ExitHandlerInsert(handler func()) {
	hMutex.Lock()
	defer hMutex.Unlock()

	handlers = append([]func(){handler}, handlers...)
}
